package public

import (
	"time"

	"github.com/gomodule/redigo/redis"
)

type RedisConf struct {
	Host         string `mapstructure:"host"`
	Password     string `mapstructure:"password"`
	Db           int    `mapstructure:"db"`
	ConnTimeout  int    `mapstructure:"conn_timeout"`
	ReadTimeout  int    `mapstructure:"read_timeout"`
	WriteTimeout int    `mapstructure:"write_timeout"`
	MaxConn      int    `mapstructure:"max_conn"`
	MaxIdle      int    `mapstructure:"max_idle"`
}

var (
	RedisPool    *redis.Pool
	RedisConfObj *RedisConf
)

func InitRedisPool() {
	RedisConfObj = &RedisConf{}
	err := BaseConf.UnmarshalKey("redis", RedisConfObj)
	if err != nil {
		panic(err)
	}

	RedisPool = &redis.Pool{
		MaxIdle:     RedisConfObj.MaxIdle,
		IdleTimeout: 240 * time.Second,
		Dial:        RedisConnFactory,
	}
}

func GetRedisConn() redis.Conn {
	return RedisPool.Get()
}

func RedisConnFactory() (redis.Conn, error) {
	c, err := redis.Dial(
		"tcp",
		RedisConfObj.Host)
	if err != nil {
		return nil, err
	}
	if RedisConfObj.Password != "" {
		if _, err := c.Do("AUTH", RedisConfObj.Password); err != nil {
			c.Close()
			return nil, err
		}
	}
	if RedisConfObj.Db != 0 {
		if _, err := c.Do("SELECT", RedisConfObj.Db); err != nil {
			c.Close()
			return nil, err
		}
	}
	return c, nil
}

func RedisConfPipline(pip ...func(c redis.Conn)) error {
	c := GetRedisConn()
	defer c.Close()
	for _, f := range pip {
		f(c)
	}
	c.Flush()
	return nil
}

func RedisConfDo(commandName string, args ...interface{}) (interface{}, error) {
	c := GetRedisConn()
	defer c.Close()
	return c.Do(commandName, args...)
}

func CloseRedisConn() {
	RedisPool.Close()
}
